import 'dart:math';

import 'package:dio/dio.dart';
import 'package:get_storage/get_storage.dart';
import 'package:hockey/jzx_apps.dart';
import 'package:hockey/jzx_models.dart';
import 'package:hockey/models/jzx_comment_data.dart';
import 'package:hockey/models/jzx_loc_data.dart';
import 'package:hockey/network/jzx_apis.dart';
import 'package:hockey/services/jzx_app.dart';
import 'package:hockey/services/jzx_user.dart';

/// 配置帖子/视频数据
class JzxConfigService extends GetxService {
  static JzxConfigService get to => Get.find();

  GetStorage box = GetStorage();

  final postAuthorList =
      List.generate(12, (index) => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[index]);
  final videoAuthorList =
      List.generate(15, (index) => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[index]);

  /// 所有的用户关联数据, 网络数据
  var bindList = <AuthtorUserBind>[];

  /// 所有的用户数据
  var users = <JzxAuthorData>[];

  /// 帖子
  var postList = <JzxMediaData>[];

  /// 视频
  var videoList = <JzxMediaData>[];

  /// 拉黑用户组 ids
  var blockList = <String>[];

  /// 好友用户组 ids
  var followList = <String>[];

  /// 所有的帖子评论
  var commentsList = <JzxCommentData>[];

  @override
  void onInit() {
    super.onInit();
    initCacheData();
  }

  reset() {
    initCacheData();
  }

  /// 缓存
  initCacheData() {
    // box.erase();
    // box.save();
    final postCache = box.read(kPostListKey) ?? [];
    final videoCache = box.read(kVideoListKey) ?? [];
    final bindCache = box.read(kBindListKey) ?? [];
    final usersCache = box.read(kUsersKey) ?? [];
    final block = box.read(kBlockUsers) ?? [];
    final follow = box.read(kFollowUsers) ?? [];
    // box.remove (kCommentListKey);
    final comments = box.read(kCommentListKey) ?? [];

    postList.clear();
    if (postCache.isEmpty) {
      for (var e in locPostList) {
        final item = JzxMediaData.fromJson(e);
        postList.add(item.copyWith(
          follow: max(item.follow, Random().nextInt(15) + 5),
          like: max(item.follow, Random().nextInt(1500) + 5),
        ));
      }
      // 初始化写入
      box.write(kPostListKey, postList.map((e) => e.toJson()).toList());
    } else {
      for (var e in postCache) {
        final item = JzxMediaData.fromJson(e);
        postList.add(item);
      }
    }

    videoList.clear();
    if (videoCache.isEmpty) {
      for (var e in locVideoList) {
        final item = JzxMediaData.fromJson(e);
        videoList.add(item.copyWith(
          follow: max(item.follow, Random().nextInt(15) + 5),
          like: max(item.follow, Random().nextInt(1500) + 5),
          type: 1,
        ));
      }
      // 初始化写入
      box.write(kVideoListKey, videoList.map((e) => e.toJson()).toList());
    } else {
      for (var e in videoCache) {
        final item = JzxMediaData.fromJson(e);
        videoList.add(item);
      }
    }

    bindList.clear();
    if (bindCache.isNotEmpty) {
      for (var e in bindCache) {
        bindList.add(AuthtorUserBind.fromJson(e));
      }
    }
    users.clear();
    if (usersCache.isNotEmpty) {
      for (var e in usersCache) {
        final item = JzxAuthorData.fromJson(e);
        users.add(item);
      }
    }

    blockList.clear();
    if (block.isNotEmpty) {
      for (var e in block) {
        blockList.add(e);
      }
    }

    followList.clear();
    if (follow.isNotEmpty) {
      for (var e in follow) {
        followList.add(e);
      }
    }

    commentsList.clear();
    if (comments.isNotEmpty) {
      for (var e in comments) {
        commentsList.add(JzxCommentData.fromJson(e));
      }
    }

    // print(bindList);
    // print(videoList);
    // print(postList);
    // updateUsersAndTidyList();
  }

  /// 用户登陆/校验token后获取数据（成功进入首页？）
  /// 获取用户数据+构建列表
  updateUsersAndTidyList() async {
    if (users.isNotEmpty && bindList.isNotEmpty) {
      // bindAuthorUser(users);
      return;
    }

    try {
      final params = {
        "category": "Popular", // 分类固定传Popular
        "isPageMode": true,
        "isRemoteImageUrl": true, // 必须为true 否则返回的头像链接需要拼接
        "limit": 20,
        "page": 1,
        "tag": "All",
      };
      final res = await JzxNetRepository.client.broadcasterWall(params);
      users =
          res.map((e) => e.copyWith(level: Random().nextInt(4) + 1)).toList();
      box.write(kUsersKey, users.map((e) => e.toJson()).toList());

      /// 绑定作者和网络数据
      /// 缓存中没有值，则构建新对应的数据
      bindAuthorUser(res);
    } catch (e) {
      // print(e);
    }
  }

  // ------------------- user bind -------------------
  /// 绑定表关系
  bindAuthorUser(
    List<JzxAuthorData> res, {
    bool force = false,
  }) {
    if (bindList.isEmpty || force) {
      bindList.clear();
      for (var i = 0; i < postAuthorList.length; i++) {
        bindList.add(AuthtorUserBind(
          author: postAuthorList[i],
          userId: res[i].userId,
        ));
      }
      for (var i = 0; i < videoAuthorList.length; i++) {
        bindList.add(
          AuthtorUserBind(
              author: videoAuthorList[i], userId: res[i].userId, type: 1),
        );
      }

      box.write(kBindListKey, bindList.map((e) => e.toJson()).toList());
    } else {
      // 校验关联表中是否包含用户数据
      bool bothContain = true;
      for (var e in bindList) {
        // 如果关联关系中userid，没有对应user数据，须重新处理
        if (!res.any((element) => element.userId == e.userId)) {
          bothContain = false;
          break;
        }
      }
      if (!bothContain) {
        // 重新绑定
        bindAuthorUser(res, force: true);
      }
    }
  }

  /// 查询用户
  JzxAuthorData findUserByAuthor(
    String author, {
    /// 0-帖子 1-视频
    int type = 0,
  }) {
    if (author == JzxUserService.to.author) {
      return JzxUserService.to.authorData;
    }

    final bind = bindList.firstWhere(
      (element) => element.author == author && element.type == type,
      orElse: () => const AuthtorUserBind(),
    );
    return users.firstWhere((element) => element.userId == bind.userId);
  }

  JzxAuthorData findUserByUid(String uid) {
    if (uid == JzxUserService.to.uid) {
      return JzxUserService.to.authorData;
    }
    return users.firstWhere((element) => element.userId == uid);
  }

  // ------------------- post -------------------

  /// 获取全部的帖子数据
  Future<List<JzxMediaData>> getCurPostList() async {
    final temp = <JzxMediaData>[];

    for (var e in postList) {
      temp.add(
        e.copyWith(
          user: findUserByAuthor(e.author),
        ),
      );
    }

    return temp;
  }

  /// 获取用户帖子
  List<JzxMediaData> getPostListByAuthor(String author) {
    final temp = <JzxMediaData>[];

    for (var e in postList) {
      if (author == e.author) {
        temp.add(
          e.copyWith(
            user: findUserByAuthor(e.author),
          ),
        );
      }
    }

    return temp;
  }

  /// 更新本地数据
  updatePostList(
    JzxMediaData item, {
    // 刷新主页数据
    bool canRefresh = false,
  }) {
    final index = postList.indexWhere((element) => element.id == item.id);
    if (index == -1) {
      // 新增
      postList.insert(0, item);
      // 完成发布任务
      JzxUserService.to.updateUnlockConditions(5);
    } else {
      postList[index] = item;
    }
    box.write(kPostListKey, postList.map((e) => e.toJson()).toList());

    //
    if (canRefresh) {
      JzxAppService.bus.fire(RefreshPostLike());
    }
  }

  // ------------------- video -------------------

  /// 获取全部的视频数据
  Future<List<JzxMediaData>> getCurVideoList(List<JzxVideoData> videos) async {
    final temp = <JzxMediaData>[];
    final count = min(videoList.length, videos.length);
    for (var i = 0; i < count; i++) {
      final item = videoList[i];
      final video = videos[i];
      temp.add(
        item.copyWith(
          user: findUserByAuthor(item.author, type: 1),
          cover: video.coverStr,
          url: video.mediaUrl,
        ),
      );
    }

    return temp;
  }

  /// 更新本地数据
  updateVideoList(
    JzxMediaData item, {
    // 刷新主页数据
    bool canRefresh = false,
  }) {
    final index = videoList.indexWhere((element) => element.id == item.id);
    if (index == -1) {
      // 新增
      videoList.insert(0, item);
      // 完成发布任务
      // JzxUserService.to.updateUnlockConditions(5);
    } else {
      videoList[index] = item;
    }
    box.write(kVideoListKey, videoList.map((e) => e.toJson()).toList());

    //
    if (canRefresh) {
      JzxAppService.bus.fire(RefreshPostLike());
    }
  }

  // ------------------- block / follow -------------------
  /// 更新本地拉黑列表
  updateBlocks(String userId) {
    // 成功删除表示衣移除，否则添加新的黑名单
    if (!blockList.remove(userId)) {
      blockList.add(userId);
    } else {
      // 移除follow
      if (isFollow(userId)) {
        JzxNetRepository.client.removeFollow({'followUserId': userId});
        updateFollows(userId);
      }
    }
    box.write(kBlockUsers, blockList);

    // 执行更新
    JzxAppService.bus.fire(RefreshBlockUsers());
  }

  /// 更新本地好友列表
  updateFollows(String userId) {
    if (!followList.remove(userId)) {
      followList.add(userId);
      JzxUserService.to.updateUnlockConditions(4);
    }
    box.write(kBlockUsers, followList);

    // 执行更新
    JzxAppService.bus.fire(RefreshFollowUsers());
  }

  /// 是否关注
  bool isFollow(String userId) {
    return followList.contains(userId);
  }

  // ------------------- translate -------------------
  /// 文字翻译到本机语言
  Future translate(String text) async {
    try {
      final md5Key = generateMD5(text);
      // 读取缓存
      final content = box.read(md5Key);
      if (content != null) {
        return '$content';
      }

      final params = {
        'key': JzxUserService.to.config.googleTranslationKey,
        'format': 'text',
        'q': text,
        'target': Get.locale?.languageCode,
      };
      final res = await Dio().post(kApiGoogleTranslate, data: params);
      // print(res);
      // 写入缓存
      box.write(md5Key, 'value');
    } catch (e) {
      // print(e);
    }
  }

  // ------------------- comments -------------------

  // void updateCommentsLike(String s) {
  // if (!commentsLikeList.remove(s)) {
  //   commentsLikeList.add(s);
  // }
  // box.write (kCommentsLike, commentsLikeList);
  // }

  /// 是否关注
  bool isCommentLike(String id) {
    final res = commentsList.where((element) => element.id == id);
    return res.isNotEmpty;
  }

  /// 获取用户帖子
  List<JzxCommentData> getCommentListById(String postId, {int pageType = 0}) {
    return commentsList
        .where((element) =>
            element.postId == postId && element.pageType == pageType)
        .toList();
  }

  /// 更新本地数据
  updateCommentList(
    JzxCommentData item, {
    // 刷新主页数据
    bool canRefresh = false,
  }) {
    final index = commentsList.indexWhere((element) => element.id == item.id);
    if (index == -1) {
      // 新增
      commentsList.insert(0, item);
    } else {
      commentsList[index] = item;
    }
    box.write(kCommentListKey, commentsList.map((e) => e.toJson()).toList());

    //
    // if (canRefresh) {
    // JzxAppService.bus.fire(RefreshPostLike(postList));
    // }
  }
}
